//
//  LFRefreshView.swift
//  SDAutoWeibo
//
//  Created by 刘健 on 16/3/29.
//  Copyright © 2016年 Clemmie. All rights reserved.
//

/// 封装一个类，或一个功能 优先考虑系统方法,不需要添加子控件，直接调用方法，降低高内聚，低耦合，暴露方法少，

import UIKit

//MARK: -- 定义下拉刷新状态
enum LFPulldownRefreshControlStatus: Int {
    case Normal         // 箭头朝下, 下拉刷新
    case PullToRefresh  // 箭头朝上, 释放刷新
    case Refreshing     // 正在刷新
}

class LFRefreshView: UIView {
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override init(frame: CGRect) {
        //自定义frame 防止外面修改
        let newFrame = CGRectMake(0, -LFRefreshViewH, UIScreen.mainScreen().bounds.width,LFRefreshViewH)
        super.init(frame: newFrame)
        
//                backgroundColor = UIColor.orangeColor()
        
        prepareUI()
    }
    
    private func prepareUI() {
        addSubview(arrowheadView)
        addSubview(fhlView)
        addSubview(tipLabel)
        
        arrowheadView.translatesAutoresizingMaskIntoConstraints = false
        fhlView.translatesAutoresizingMaskIntoConstraints = false
        tipLabel.translatesAutoresizingMaskIntoConstraints = false
        
        fhlView.hidden = true
        
        //箭头布局
        addConstraint( NSLayoutConstraint(item: arrowheadView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0))
        addConstraint( NSLayoutConstraint(item: arrowheadView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: -30))
        
        // 风火轮
        addConstraint(NSLayoutConstraint(item: fhlView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: arrowheadView, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0))
        addConstraint(NSLayoutConstraint(item: fhlView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: arrowheadView, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0))
        
        // messageLabel
        addConstraint(NSLayoutConstraint(item: tipLabel, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: arrowheadView, attribute: NSLayoutAttribute.Trailing, multiplier: 1, constant: 10))
        addConstraint(NSLayoutConstraint(item: tipLabel, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: arrowheadView, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0))
    }
    
    //MARK: -- 属性
    
    //声明闭包 保存刷新状态
   private var LF_refreshingHandler: (() ->())?
    
    //定义父类时,用!
    private var scrollView: UIScrollView!
    
    //记录旧的状态
    var oldStatus = LFPulldownRefreshControlStatus.Normal
    
    private var currentStatus: LFPulldownRefreshControlStatus = .Normal {
        //处理不同状态下的UI
        didSet {
            
            switch currentStatus {
                //箭头朝下, 下拉刷新
            case .Normal:
                //风火轮 隐藏 并且移除动画
                fhlView.layer.removeAllAnimations()
                fhlView.hidden = true
                //箭头 显示
                arrowheadView.hidden = false
                tipLabel.text = "下拉刷新..."
                UIView .animateWithDuration(LFRefreshAnimationTime, animations: { () -> Void in
                    self.arrowheadView.transform = CGAffineTransformIdentity
                })
                
                if oldStatus == .Refreshing {
                    
                    UIView.animateWithDuration(LFRefreshAnimationTime * 2, animations: { () -> Void in
                        self.scrollView.contentInset.top -= LFRefreshViewH
                    })
                }
                break
                //箭头朝上, 释放刷新
            case .PullToRefresh:
                //1风火轮 隐藏
                fhlView.hidden = true
                //2箭头 显示
                arrowheadView.hidden = false
                //3更改提示
                tipLabel.text = "松手刷新..."
                //4加上动画
                UIView .animateWithDuration(LFRefreshAnimationTime, animations: { () -> Void in
                    self.arrowheadView.transform = CGAffineTransformMakeRotation(CGFloat(M_PI))
                })
                break
                //正在刷新
            case .Refreshing:
                //1风火轮 显示
                fhlView.hidden = false
                //2箭头 隐藏
                arrowheadView.hidden = true
                //3更改提示
                tipLabel.text = "正在刷新..."
                //添加动画
                let animation = CABasicAnimation(keyPath: "transform.rotation")
                //动画时间
                animation.duration = 1;
                //动画次数
                animation.repeatCount = MAXFLOAT
                //动画轨迹
                animation.toValue = M_PI*2
                //添加动画
                fhlView.layer.addAnimation(animation, forKey: "rotation")
                
                //记录父View的偏移值
                UIView.animateWithDuration(LFRefreshAnimationTime, animations: { () -> Void in
                    self.scrollView.contentInset.top += LFRefreshViewH
                    }, completion: { (_) -> Void in
                        //调用闭包，保存状态
                        self.LF_refreshingHandler?()
                })
                break
            }
            //记录每次动作时动态
            oldStatus = currentStatus;
        }
    }
    
    //MARK: -- 即将添加到父类时调用，newSuperview为父类
    override func willMoveToSuperview(newSuperview: UIView?) {
        
        if let scrollView = newSuperview as? UIScrollView {
            
            self.scrollView = scrollView
            
            //使用KVO 监听值得变化
            scrollView.addObserver(self, forKeyPath: "contentOffset", options: NSKeyValueObservingOptions(rawValue: 0), context: nil)
        }
    }
    //MARK: -- KVO监听 设置状态
    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        
//        print("\(scrollView.contentOffset.y)");
        
        if scrollView.dragging {
            let contentOffsetY = scrollView.contentOffset.y
            
            if contentOffsetY >= -self.scrollView.contentInset.top - LFRefreshViewH && currentStatus == .PullToRefresh {
                currentStatus = .Normal;
            } else if contentOffsetY < -self.scrollView.contentInset.top - LFRefreshViewH && currentStatus == .Normal {
                currentStatus = .PullToRefresh
            }
        }else if currentStatus == .PullToRefresh {
            currentStatus = .Refreshing
        }
        
    }
    
    //MARK: -- 移除KVO
    deinit{
        self.scrollView.removeObserver(self, forKeyPath: "contentOffset")
    }
    
    //MARK: -- 公开调用方法
    //结束刷新
    private func endRefreshing() {
        //变为普通状态
        currentStatus = .Normal
    }
    //开始刷新
    private func startRefreshing() {
        currentStatus = .Refreshing
    }
    
    //MARK: -- 箭头
    private lazy var arrowheadView: UIImageView = {
        let image = UIImageView()
        image.image = UIImage(named: "tableview_pull_refresh")
        return image
    }()
    
    /// 风火轮
    private lazy var fhlView: UIImageView = UIImageView(image: UIImage(named: "tableview_loading"))
    
    
    private lazy var tipLabel: UILabel = {
        let label = UILabel()
        
        label.text = "下拉刷新..."
        label.textAlignment = NSTextAlignment.Center
        label.font = UIFont.systemFontOfSize(14)
        label.textColor = UIColor.grayColor()
        return label
    }()
}

//runtime运行时 key
private var LF_RefreshViewObjcKey = "LF_RefreshViewObjcKey"

//MARK: -- 为UIScrollView添加一个View拥有下拉刷新控件 使用runtime运行时
extension UIScrollView {
    private var refreshView: LFRefreshView  {
        get {
            //添加时一定要加&
            if let view  = objc_getAssociatedObject(self, &LF_RefreshViewObjcKey) as? LFRefreshView {
                return view
            }else {
                //添加到UIScrollView
                let RefreshView = LFRefreshView()
                
                self.addSubview(RefreshView)
                
                //关联对象
                self.refreshView = RefreshView
                
                return RefreshView
            }
        }
        
        set {
            
            objc_setAssociatedObject(self, &LF_RefreshViewObjcKey, newValue,objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    //MARK: -- 封装方法
    //1.封装开始刷新闭包
    func LF_refreshingHandlerBlock(handler: () -> ()) {
        refreshView.LF_refreshingHandler = handler
    }
    //2.开始刷新
    func LF_stratRefreshing() {
        refreshView.startRefreshing()
    }
    //3.结束刷新
    func LF_endRefreshing() {
        refreshView.endRefreshing()
    }
}







